summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShih-wei Liao <sliao@google.com>2011-08-08 06:03:12 -0700
committerShih-wei Liao <sliao@google.com>2011-08-09 06:18:35 -0700
commit768a6e8961ae16a5bcf6cab2b21405306b259a0b (patch)
tree880344c0d7a0baece062caccd2ad3d391783e522
parentfa06e91015017e8d0627d26a88e2a575643bec11 (diff)
downloadlinkloader-768a6e8961ae16a5bcf6cab2b21405306b259a0b.tar.gz
Count size for common variable before relocate.
BUG=5057160. Tested on x86, crespo and stingray. TODO: I did a workaround for .lcomm directives bug of LLVM ARM MC code generator. Remove this when the LLVM bug is fixed. TODO: Need to refactor initSHNCommonDataSize. Change-Id: I060c5306586224ddb92e79744c80f2a5925b3dff
-rw-r--r--include/ELFObject.h24
-rw-r--r--include/impl/ELFObject.hxx45
2 files changed, 58 insertions, 11 deletions
diff --git a/include/ELFObject.h b/include/ELFObject.h
index db3150e..a1a25b9 100644
--- a/include/ELFObject.h
+++ b/include/ELFObject.h
@@ -41,6 +41,18 @@ private:
unsigned char *SHNCommonDataPtr;
size_t SHNCommonDataFreeSize;
+ // TODO: Need refactor!
+ bool initSHNCommonDataSize(size_t SHNCommonDataSize) {
+ rsl_assert(!SHNCommonDataPtr && "Can't init twice.");
+ if (!SHNCommonData.allocate(SHNCommonDataSize)) {
+ return false;
+ }
+
+ SHNCommonDataPtr = SHNCommonData.getBuffer();
+ SHNCommonDataFreeSize = SHNCommonDataSize;
+ return true;
+ }
+
private:
ELFObject() : SHNCommonDataPtr(NULL) { }
@@ -65,17 +77,7 @@ public:
void *allocateSHNCommonData(size_t size, size_t align = 1) {
rsl_assert(size > 0 && align != 0);
- enum { SHN_COMMON_DATA_SIZE = 0x40000 };
-
- if (!SHNCommonDataPtr) {
- // FIXME: We should not hard code these number!
- if (!SHNCommonData.allocate(SHN_COMMON_DATA_SIZE)) {
- return NULL;
- }
-
- SHNCommonDataPtr = SHNCommonData.getBuffer();
- SHNCommonDataFreeSize = SHN_COMMON_DATA_SIZE;
- }
+ rsl_assert(SHNCommonDataPtr && "Must init common data size before use!");
// Ensure alignment
size_t rem = ((uintptr_t)SHNCommonDataPtr) % align;
diff --git a/include/impl/ELFObject.hxx b/include/impl/ELFObject.hxx
index 279a850..680cc4d 100644
--- a/include/impl/ELFObject.hxx
+++ b/include/impl/ELFObject.hxx
@@ -335,9 +335,54 @@ relocateX86_32(void *(*find_sym)(void *context, char const *name),
}
}
+// TODO: Refactor all relocations.
template <unsigned Bitwidth>
inline void ELFObject<Bitwidth>::
relocate(void *(*find_sym)(void *context, char const *name), void *context) {
+ // Init SHNCommonDataSize.
+ // Need refactoring
+ size_t SHNCommonDataSize = 0;
+
+ ELFSectionSymTabTy *symtab =
+ static_cast<ELFSectionSymTabTy *>(getSectionByName(".symtab"));
+ rsl_assert(symtab && "Symtab is required.");
+
+ for (size_t i = 0; i < symtab->size(); ++i) {
+ ELFSymbolTy *sym = (*symtab)[i];
+
+ if (sym->getType() != STT_OBJECT) {
+ continue;
+ }
+
+ size_t idx = (size_t)sym->getSectionIndex();
+ switch (idx) {
+ default:
+ if ((*shtab)[idx]->getType() == 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;
+ SHNCommonDataSize += (size_t)sym->getSize() + align;
+ }
+ break;
+
+ case SHN_COMMON:
+ {
+ size_t align = 16;
+ SHNCommonDataSize += (size_t)sym->getSize() + align;
+ }
+ break;
+
+ case SHN_ABS:
+ case SHN_UNDEF:
+ case SHN_XINDEX:
+ break;
+ }
+ }
+ if (!initSHNCommonDataSize(SHNCommonDataSize)) {
+ rsl_assert("Allocate memory for common variable fail!");
+ }
for (size_t i = 0; i < stab.size(); ++i) {
ELFSectionHeaderTy *sh = (*shtab)[i];