1e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao/*
2e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao * Copyright 2011, The Android Open Source Project
3e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao *
4e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao * Licensed under the Apache License, Version 2.0 (the "License");
5e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao * you may not use this file except in compliance with the License.
6e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao * You may obtain a copy of the License at
7e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao *
8e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao *     http://www.apache.org/licenses/LICENSE-2.0
9e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao *
10e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao * Unless required by applicable law or agreed to in writing, software
11e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao * distributed under the License is distributed on an "AS IS" BASIS,
12e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao * See the License for the specific language governing permissions and
14e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao * limitations under the License.
15e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao */
16e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao
17ec39cb4e115b0e6a7cebbe1d190c93a8702d7f12Logan Chien#ifndef ELF_OBJECT_H
18ec39cb4e115b0e6a7cebbe1d190c93a8702d7f12Logan Chien#define ELF_OBJECT_H
19ec39cb4e115b0e6a7cebbe1d190c93a8702d7f12Logan Chien
2058611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien#include "ELFTypes.h"
219f64da291148a9c09bef5d062e9047bff64f56b9Logan Chien#include "MemChunk.h"
2258611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien
23c40d8a8b26547ab9c51792d9d9b3aca13fb5cdf9TDYa#include "utils/rsl_assert.h"
24c40d8a8b26547ab9c51792d9d9b3aca13fb5cdf9TDYa
251f100419d794fa433336190aa47bb0862f93f978TDYa#include <llvm/ADT/OwningPtr.h>
2645587de75f78eb78b400e733d47b6e7d702b55b4Logan Chien
275c543a0761c5a7f72565351bc16ec31d6f675602TDYa#include <string>
28919742fa8a24a869172e6cb6ac09301cbf753532Logan Chien#include <vector>
29921465005aca46a100d137c9608a0aedd846e290Logan Chien
30a9ab5889e842a49ff16d06594efe96b0210fe1f7Logan Chientemplate <unsigned Bitwidth>
31ec39cb4e115b0e6a7cebbe1d190c93a8702d7f12Logan Chienclass ELFObject {
3258611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chienpublic:
3358611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien  ELF_TYPE_INTRO_TO_TEMPLATE_SCOPE(Bitwidth);
3458611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien
35ec39cb4e115b0e6a7cebbe1d190c93a8702d7f12Logan Chienprivate:
3658611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien  llvm::OwningPtr<ELFHeaderTy> header;
3758611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien  llvm::OwningPtr<ELFSectionHeaderTableTy> shtab;
3858611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien  std::vector<ELFSectionTy *> stab;
39ec39cb4e115b0e6a7cebbe1d190c93a8702d7f12Logan Chien
409f64da291148a9c09bef5d062e9047bff64f56b9Logan Chien  MemChunk SHNCommonData;
419f64da291148a9c09bef5d062e9047bff64f56b9Logan Chien  unsigned char *SHNCommonDataPtr;
429f64da291148a9c09bef5d062e9047bff64f56b9Logan Chien  size_t SHNCommonDataFreeSize;
439f64da291148a9c09bef5d062e9047bff64f56b9Logan Chien
4450b814ae8797a929bc0416d6a97e3551b24eaf30Stephen Hines  bool missingSymbols;
4550b814ae8797a929bc0416d6a97e3551b24eaf30Stephen Hines
46768a6e8961ae16a5bcf6cab2b21405306b259a0bShih-wei Liao  // TODO: Need refactor!
47768a6e8961ae16a5bcf6cab2b21405306b259a0bShih-wei Liao  bool initSHNCommonDataSize(size_t SHNCommonDataSize) {
48768a6e8961ae16a5bcf6cab2b21405306b259a0bShih-wei Liao    rsl_assert(!SHNCommonDataPtr && "Can't init twice.");
49768a6e8961ae16a5bcf6cab2b21405306b259a0bShih-wei Liao    if (!SHNCommonData.allocate(SHNCommonDataSize)) {
50768a6e8961ae16a5bcf6cab2b21405306b259a0bShih-wei Liao      return false;
51768a6e8961ae16a5bcf6cab2b21405306b259a0bShih-wei Liao    }
52768a6e8961ae16a5bcf6cab2b21405306b259a0bShih-wei Liao
53768a6e8961ae16a5bcf6cab2b21405306b259a0bShih-wei Liao    SHNCommonDataPtr = SHNCommonData.getBuffer();
54768a6e8961ae16a5bcf6cab2b21405306b259a0bShih-wei Liao    SHNCommonDataFreeSize = SHNCommonDataSize;
55768a6e8961ae16a5bcf6cab2b21405306b259a0bShih-wei Liao    return true;
56768a6e8961ae16a5bcf6cab2b21405306b259a0bShih-wei Liao  }
57768a6e8961ae16a5bcf6cab2b21405306b259a0bShih-wei Liao
58ec39cb4e115b0e6a7cebbe1d190c93a8702d7f12Logan Chienprivate:
5950b814ae8797a929bc0416d6a97e3551b24eaf30Stephen Hines  ELFObject() : SHNCommonDataPtr(NULL), missingSymbols(false) { }
60ec39cb4e115b0e6a7cebbe1d190c93a8702d7f12Logan Chien
61ec39cb4e115b0e6a7cebbe1d190c93a8702d7f12Logan Chienpublic:
62ec39cb4e115b0e6a7cebbe1d190c93a8702d7f12Logan Chien  template <typename Archiver>
631f100419d794fa433336190aa47bb0862f93f978TDYa  static ELFObject *read(Archiver &AR);
64ec39cb4e115b0e6a7cebbe1d190c93a8702d7f12Logan Chien
6558611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien  ELFHeaderTy const *getHeader() const {
6661dfca9e892597db79889addb7a3abf54cd50588Logan Chien    return header.get();
67ec39cb4e115b0e6a7cebbe1d190c93a8702d7f12Logan Chien  }
68ec39cb4e115b0e6a7cebbe1d190c93a8702d7f12Logan Chien
6958611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien  ELFSectionHeaderTableTy const *getSectionHeaderTable() const {
70c9a043b2ef9ec31f898b437d32d17faf7fdace6eTDYa    return shtab.get();
71c9a043b2ef9ec31f898b437d32d17faf7fdace6eTDYa  }
72c9a043b2ef9ec31f898b437d32d17faf7fdace6eTDYa
7355b5e7c242e599b88f5727352758808461483000Logan Chien  char const *getSectionName(size_t i) const;
7458611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien  ELFSectionTy const *getSectionByIndex(size_t i) const;
7558611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien  ELFSectionTy *getSectionByIndex(size_t i);
7658611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien  ELFSectionTy const *getSectionByName(std::string const &str) const;
7758611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien  ELFSectionTy *getSectionByName(std::string const &str);
785c543a0761c5a7f72565351bc16ec31d6f675602TDYa
7950b814ae8797a929bc0416d6a97e3551b24eaf30Stephen Hines  inline bool getMissingSymbols() const {
8050b814ae8797a929bc0416d6a97e3551b24eaf30Stephen Hines    return missingSymbols;
8150b814ae8797a929bc0416d6a97e3551b24eaf30Stephen Hines  }
8250b814ae8797a929bc0416d6a97e3551b24eaf30Stephen Hines
839f64da291148a9c09bef5d062e9047bff64f56b9Logan Chien  void *allocateSHNCommonData(size_t size, size_t align = 1) {
84c40d8a8b26547ab9c51792d9d9b3aca13fb5cdf9TDYa    rsl_assert(size > 0 && align != 0);
859f64da291148a9c09bef5d062e9047bff64f56b9Logan Chien
86768a6e8961ae16a5bcf6cab2b21405306b259a0bShih-wei Liao    rsl_assert(SHNCommonDataPtr && "Must init common data size before use!");
879f64da291148a9c09bef5d062e9047bff64f56b9Logan Chien
889f64da291148a9c09bef5d062e9047bff64f56b9Logan Chien    // Ensure alignment
899f64da291148a9c09bef5d062e9047bff64f56b9Logan Chien    size_t rem = ((uintptr_t)SHNCommonDataPtr) % align;
909f64da291148a9c09bef5d062e9047bff64f56b9Logan Chien    if (rem != 0) {
919f64da291148a9c09bef5d062e9047bff64f56b9Logan Chien      SHNCommonDataPtr += align - rem;
929f64da291148a9c09bef5d062e9047bff64f56b9Logan Chien      SHNCommonDataFreeSize -= align - rem;
939f64da291148a9c09bef5d062e9047bff64f56b9Logan Chien    }
949f64da291148a9c09bef5d062e9047bff64f56b9Logan Chien
959f64da291148a9c09bef5d062e9047bff64f56b9Logan Chien    // Ensure the free size is sufficient
969f64da291148a9c09bef5d062e9047bff64f56b9Logan Chien    if (SHNCommonDataFreeSize < size) {
979f64da291148a9c09bef5d062e9047bff64f56b9Logan Chien      return NULL;
989f64da291148a9c09bef5d062e9047bff64f56b9Logan Chien    }
999f64da291148a9c09bef5d062e9047bff64f56b9Logan Chien
1009f64da291148a9c09bef5d062e9047bff64f56b9Logan Chien    // Allcoate
1019f64da291148a9c09bef5d062e9047bff64f56b9Logan Chien    void *result = SHNCommonDataPtr;
1029f64da291148a9c09bef5d062e9047bff64f56b9Logan Chien    SHNCommonDataPtr += size;
1039f64da291148a9c09bef5d062e9047bff64f56b9Logan Chien    SHNCommonDataFreeSize -= size;
1049f64da291148a9c09bef5d062e9047bff64f56b9Logan Chien
1059f64da291148a9c09bef5d062e9047bff64f56b9Logan Chien    return result;
1069f64da291148a9c09bef5d062e9047bff64f56b9Logan Chien  }
1079f64da291148a9c09bef5d062e9047bff64f56b9Logan Chien
1084e4356b34f9751070ac8ccb1bb74bb44e9232661Logan Chien  void relocate(void *(*find_sym)(void *context, char const *name),
1095c543a0761c5a7f72565351bc16ec31d6f675602TDYa                void *context);
11055b5e7c242e599b88f5727352758808461483000Logan Chien
111af521b05a143c96604dbb7488e155c5248e34462Logan Chien  void print() const;
1121f100419d794fa433336190aa47bb0862f93f978TDYa
1131f100419d794fa433336190aa47bb0862f93f978TDYa  ~ELFObject() {
1141f100419d794fa433336190aa47bb0862f93f978TDYa    for (size_t i = 0; i < stab.size(); ++i) {
1151f100419d794fa433336190aa47bb0862f93f978TDYa      // Delete will check the pointer is nullptr or not by himself.
1161f100419d794fa433336190aa47bb0862f93f978TDYa      delete stab[i];
1171f100419d794fa433336190aa47bb0862f93f978TDYa    }
1181f100419d794fa433336190aa47bb0862f93f978TDYa  }
119f11d38331d835997c31d30519e0402971266bf1aLogan Chien
120f11d38331d835997c31d30519e0402971266bf1aLogan Chienprivate:
1214e4356b34f9751070ac8ccb1bb74bb44e9232661Logan Chien  void relocateARM(void *(*find_sym)(void *context, char const *name),
122a13b6909c66260aabbcd32b6519d05e469881141TDYa                   void *context,
123a13b6909c66260aabbcd32b6519d05e469881141TDYa                   ELFSectionRelTableTy *reltab,
124a13b6909c66260aabbcd32b6519d05e469881141TDYa                   ELFSectionProgBitsTy *text);
125f11d38331d835997c31d30519e0402971266bf1aLogan Chien
1264e4356b34f9751070ac8ccb1bb74bb44e9232661Logan Chien  void relocateX86_32(void *(*find_sym)(void *context, char const *name),
127a13b6909c66260aabbcd32b6519d05e469881141TDYa                      void *context,
128a13b6909c66260aabbcd32b6519d05e469881141TDYa                      ELFSectionRelTableTy *reltab,
129a13b6909c66260aabbcd32b6519d05e469881141TDYa                      ELFSectionProgBitsTy *text);
130f11d38331d835997c31d30519e0402971266bf1aLogan Chien
1314e4356b34f9751070ac8ccb1bb74bb44e9232661Logan Chien  void relocateX86_64(void *(*find_sym)(void *context, char const *name),
132a13b6909c66260aabbcd32b6519d05e469881141TDYa                      void *context,
133a13b6909c66260aabbcd32b6519d05e469881141TDYa                      ELFSectionRelTableTy *reltab,
134a13b6909c66260aabbcd32b6519d05e469881141TDYa                      ELFSectionProgBitsTy *text);
135f11d38331d835997c31d30519e0402971266bf1aLogan Chien
1362ffd160f255552e33f4b393d3097a3525e204634Shih-wei Liao  void relocateMIPS(void *(*find_sym)(void *context, char const *name),
1372ffd160f255552e33f4b393d3097a3525e204634Shih-wei Liao                    void *context,
1382ffd160f255552e33f4b393d3097a3525e204634Shih-wei Liao                    ELFSectionRelTableTy *reltab,
1392ffd160f255552e33f4b393d3097a3525e204634Shih-wei Liao                    ELFSectionProgBitsTy *text);
140ec39cb4e115b0e6a7cebbe1d190c93a8702d7f12Logan Chien};
141ec39cb4e115b0e6a7cebbe1d190c93a8702d7f12Logan Chien
142089c5b3d98c8e4416a36cff12199c9ea659d8976Logan Chien#include "impl/ELFObject.hxx"
143af521b05a143c96604dbb7488e155c5248e34462Logan Chien
144ec39cb4e115b0e6a7cebbe1d190c93a8702d7f12Logan Chien#endif // ELF_OBJECT_H
145