summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLogan Chien <tzuhsiang.chien@gmail.com>2011-07-02 03:13:28 +0800
committerLogan Chien <tzuhsiang.chien@gmail.com>2011-07-02 03:34:27 +0800
commit1045a1dabf49181e7cba2e37a891799ba9055d9f (patch)
tree11035cbbab96a738537a39c4e1aadddd13d8288d
parent86196e389f2616e218de17920b6fe23d24f67786 (diff)
downloadlinkloader-1045a1dabf49181e7cba2e37a891799ba9055d9f.tar.gz
Rewrite the workaround for misalignment.
Previous workaround caused RsBenchmark crashed. This is because the inconsistency of the symbol address and relocation address. In the old patch, the relocation hole will be filled with new aligned address, while the relocation process will committed on old address. This new workaround is based on the observation that ".lcomm" directive bug will only affect .bss section (NOBITS). Besides, .bss section itself needs no relocation. So it is OK to allocate 16-byte aligned memory for .bss section.
-rw-r--r--include/impl/ELFSymbol.hxx44
1 files changed, 27 insertions, 17 deletions
diff --git a/include/impl/ELFSymbol.hxx b/include/impl/ELFSymbol.hxx
index c632f8c..d7e127b 100644
--- a/include/impl/ELFSymbol.hxx
+++ b/include/impl/ELFSymbol.hxx
@@ -137,27 +137,37 @@ void *ELFSymbol_CRTP<Bitwidth>::getAddress(bool autoAlloc) const {
switch (idx) {
default:
{
-#ifndef NDEBUG
ELFSectionHeaderTableTy const *header =
owner->getSectionHeaderTable();
- rsl_assert(((*header)[idx]->getType() == SHT_PROGBITS ||
- (*header)[idx]->getType() == SHT_NOBITS) &&
- "STT_OBJECT with not BITS section.");
-#endif
- ELFSectionTy const *sec = owner->getSectionByIndex(idx);
- rsl_assert(sec != 0 && "STT_OBJECT with null section.");
- size_t align = 16;
- my_addr = const_cast<ELFObjectTy *>(owner)->
- allocateSHNCommonData((size_t)getSize(), align);
- if (!my_addr) {
- rsl_assert(0 && "Unable to allocate memory for SHN_COMMON.");
- abort();
- }
+ unsigned section_type = (*header)[idx]->getType();
- ELFSectionBitsTy const &st =
- static_cast<ELFSectionBitsTy const &>(*sec);
- memcpy(my_addr, &st[0] + (off_t)getValue(), getSize());
+ rsl_assert((section_type == SHT_PROGBITS ||
+ section_type == SHT_NOBITS) &&
+ "STT_OBJECT with not BITS section.");
+
+ if (section_type == SHT_NOBITS) {
+ // FIXME(logan): This is a workaround for .lcomm directives
+ // bug of LLVM ARM MC code generator. Remove this when the
+ // LLVM bug is fixed.
+
+ size_t align = 16;
+
+ my_addr = const_cast<ELFObjectTy *>(owner)->
+ allocateSHNCommonData((size_t)getSize(), align);
+
+ if (!my_addr) {
+ rsl_assert(0 && "Unable to allocate memory for SHN_COMMON.");
+ abort();
+ }
+ } else {
+ ELFSectionTy const *sec = owner->getSectionByIndex(idx);
+ rsl_assert(sec != 0 && "STT_OBJECT with null section.");
+
+ ELFSectionBitsTy const &st =
+ static_cast<ELFSectionBitsTy const &>(*sec);
+ my_addr =const_cast<unsigned char *>(&st[0] + (off_t)getValue());
+ }
#if 0
#ifdef __arm__