DebugString.cpp revision 37b74a387bb3993387029859c2d9d051c41c724e
1//===- DebugString.cpp ----------------------------------------------------===// 2// 3// The MCLinker Project 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9#include "mcld/LD/DebugString.h" 10#include "mcld/LD/LDSection.h" 11#include "mcld/LD/LDSymbol.h" 12#include "mcld/LD/RelocData.h" 13#include "mcld/LD/ResolveInfo.h" 14#include "mcld/LD/SectionData.h" 15#include "mcld/Fragment/Fragment.h" 16#include "mcld/Fragment/RegionFragment.h" 17#include "mcld/Fragment/Relocation.h" 18#include "mcld/Target/TargetLDBackend.h" 19#include "mcld/LD/Relocator.h" 20 21#include <llvm/Support/Casting.h> 22#include <llvm/Support/ManagedStatic.h> 23 24namespace mcld { 25 26// DebugString represents the output .debug_str section, which is at most on 27// in each linking 28static llvm::ManagedStatic<DebugString> g_DebugString; 29 30static inline size_t string_length(const char* pStr) { 31 const char* p = pStr; 32 size_t len = 0; 33 for (; *p != 0; ++p) 34 ++len; 35 return len; 36} 37 38//========================== 39// DebugString 40void DebugString::merge(LDSection& pSection) { 41 // get the fragment contents 42 llvm::StringRef strings; 43 SectionData::iterator it, end = pSection.getSectionData()->end(); 44 for (it = pSection.getSectionData()->begin(); it != end; ++it) { 45 if ((*it).getKind() == Fragment::Region) { 46 RegionFragment* frag = llvm::cast<RegionFragment>(&(*it)); 47 strings = frag->getRegion().data(); 48 } 49 } 50 51 // get the debug strings and add them into merged string table 52 const char* str = strings.data(); 53 const char* str_end = str + pSection.size(); 54 while (str < str_end) { 55 size_t len = string_length(str); 56 m_StringTable.insertString(llvm::StringRef(str, len)); 57 str = str + len + 1; 58 } 59} 60 61size_t DebugString::computeOffsetSize() { 62 size_t size = m_StringTable.finalizeOffset(); 63 m_pSection->setSize(size); 64 return size; 65} 66 67void DebugString::applyOffset(Relocation& pReloc, TargetLDBackend& pBackend) { 68 // get the refered string 69 ResolveInfo* info = pReloc.symInfo(); 70 // the symbol should point to the first region fragment in the debug 71 // string section, get the input .debut_str region 72 llvm::StringRef d_str; 73 if (info->outSymbol()->fragRef()->frag()->getKind() == Fragment::Region) { 74 RegionFragment* frag = 75 llvm::cast<RegionFragment>(info->outSymbol()->fragRef()->frag()); 76 d_str = frag->getRegion(); 77 } 78 uint32_t offset = pBackend.getRelocator()->getDebugStringOffset(pReloc); 79 const char* str = d_str.data() + offset; 80 81 // apply the relocation 82 pBackend.getRelocator()->applyDebugStringOffset(pReloc, 83 m_StringTable.getOutputOffset(llvm::StringRef(str, string_length(str)))); 84} 85 86void DebugString::emit(MemoryRegion& pRegion) { 87 return m_StringTable.emit(pRegion); 88} 89 90DebugString* DebugString::Create(LDSection& pSection) { 91 g_DebugString->setOutputSection(pSection); 92 return &(*g_DebugString); 93} 94 95} // namespace mcld 96