You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
96 lines
3.0 KiB
96 lines
3.0 KiB
//===- DebugString.cpp ----------------------------------------------------===//
|
|
//
|
|
// The MCLinker Project
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
#include "mcld/LD/DebugString.h"
|
|
#include "mcld/LD/LDSection.h"
|
|
#include "mcld/LD/LDSymbol.h"
|
|
#include "mcld/LD/RelocData.h"
|
|
#include "mcld/LD/ResolveInfo.h"
|
|
#include "mcld/LD/SectionData.h"
|
|
#include "mcld/Fragment/Fragment.h"
|
|
#include "mcld/Fragment/RegionFragment.h"
|
|
#include "mcld/Fragment/Relocation.h"
|
|
#include "mcld/Target/TargetLDBackend.h"
|
|
#include "mcld/LD/Relocator.h"
|
|
|
|
#include <llvm/Support/Casting.h>
|
|
#include <llvm/Support/ManagedStatic.h>
|
|
|
|
namespace mcld {
|
|
|
|
// DebugString represents the output .debug_str section, which is at most on
|
|
// in each linking
|
|
static llvm::ManagedStatic<DebugString> g_DebugString;
|
|
|
|
static inline size_t string_length(const char* pStr) {
|
|
const char* p = pStr;
|
|
size_t len = 0;
|
|
for (; *p != 0; ++p)
|
|
++len;
|
|
return len;
|
|
}
|
|
|
|
//==========================
|
|
// DebugString
|
|
void DebugString::merge(LDSection& pSection) {
|
|
// get the fragment contents
|
|
llvm::StringRef strings;
|
|
SectionData::iterator it, end = pSection.getSectionData()->end();
|
|
for (it = pSection.getSectionData()->begin(); it != end; ++it) {
|
|
if ((*it).getKind() == Fragment::Region) {
|
|
RegionFragment* frag = llvm::cast<RegionFragment>(&(*it));
|
|
strings = frag->getRegion().data();
|
|
}
|
|
}
|
|
|
|
// get the debug strings and add them into merged string table
|
|
const char* str = strings.data();
|
|
const char* str_end = str + pSection.size();
|
|
while (str < str_end) {
|
|
size_t len = string_length(str);
|
|
m_StringTable.insertString(llvm::StringRef(str, len));
|
|
str = str + len + 1;
|
|
}
|
|
}
|
|
|
|
size_t DebugString::computeOffsetSize() {
|
|
size_t size = m_StringTable.finalizeOffset();
|
|
m_pSection->setSize(size);
|
|
return size;
|
|
}
|
|
|
|
void DebugString::applyOffset(Relocation& pReloc, TargetLDBackend& pBackend) {
|
|
// get the refered string
|
|
ResolveInfo* info = pReloc.symInfo();
|
|
// the symbol should point to the first region fragment in the debug
|
|
// string section, get the input .debut_str region
|
|
llvm::StringRef d_str;
|
|
if (info->outSymbol()->fragRef()->frag()->getKind() == Fragment::Region) {
|
|
RegionFragment* frag =
|
|
llvm::cast<RegionFragment>(info->outSymbol()->fragRef()->frag());
|
|
d_str = frag->getRegion();
|
|
}
|
|
uint32_t offset = pBackend.getRelocator()->getDebugStringOffset(pReloc);
|
|
const char* str = d_str.data() + offset;
|
|
|
|
// apply the relocation
|
|
pBackend.getRelocator()->applyDebugStringOffset(pReloc,
|
|
m_StringTable.getOutputOffset(llvm::StringRef(str, string_length(str))));
|
|
}
|
|
|
|
void DebugString::emit(MemoryRegion& pRegion) {
|
|
return m_StringTable.emit(pRegion);
|
|
}
|
|
|
|
DebugString* DebugString::Create(LDSection& pSection) {
|
|
g_DebugString->setOutputSection(pSection);
|
|
return &(*g_DebugString);
|
|
}
|
|
|
|
} // namespace mcld
|