00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #ifndef ipc_symtab_merge_INCLUDED
00042 #define ipc_symtab_merge_INCLUDED
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 #define WHIRL_ST_IDX_UNINITIALIZED (0)
00057 #define WHIRL_ST_IDX_NOT_AVAILABLE (-1)
00058
00059 #ifdef __cplusplus
00060
00061 #include <map>
00062
00063
00064 enum AUX_ST_FLAG
00065 {
00066
00067
00068 USED_IN_OBJ = 0x00000001,
00069 USED_IN_DSO = 0x00000002,
00070 DEF_IN_OBJ = 0x00000004,
00071 DEF_IN_DSO = 0x00000008,
00072 OBJ_COMMON = 0x00000010,
00073 ADDR_TAKEN_IN_OBJ = 0x00000020,
00074
00075
00076 OBJ_ATTR_MASK = 0x0000003f,
00077
00078
00079
00080 COMMON_USED_IN_IO = 0x00000040,
00081 IGNORE_REFCOUNTS = 0x00000080
00082
00083 };
00084
00085 extern "C" void
00086 Sync_symbol_attributes (ST_IDX st_idx, UINT32 sym_attr, BOOL is_weak,
00087 UINT32 export_class);
00088 #ifdef SHARED_BUILD
00089 #pragma weak Sync_symbol_attributes
00090 #endif
00091
00092 extern "C" void
00093 Linker_mark_not_gp_rel (ST_IDX st_idx);
00094 #ifdef SHARED_BUILD
00095 #pragma weak Linker_mark_not_gp_rel
00096 #endif
00097
00098 #endif
00099
00100 #ifndef _LD_IPA_INTERFACE
00101
00102 #include <vector>
00103
00104 #ifndef mempool_allocator_INCLUDED
00105 #include "mempool_allocator.h"
00106 #endif
00107
00108 #ifndef symtab_INCLUDED
00109 #include "symtab.h"
00110 #endif
00111
00112 #ifndef ipa_cg_INCLUDED
00113 #include "ipa_cg.h"
00114 #endif
00115
00116 const UINT32 UNINITIALIZED_INDEX = 0;
00117
00118 typedef vector<mUINT32, mempool_allocator<mUINT32> > IPC_IDX_VECTOR;
00119
00120
00121
00122
00123
00124 struct IPC_GLOBAL_TABS
00125 {
00126 void *p_obj;
00127
00128 UINT32 symstr_tab_size;
00129 UINT32 tconstr_tab_size;
00130 UINT32 pu_tab_size;
00131 UINT32 st_tab_size;
00132 UINT32 ty_tab_size;
00133 UINT32 tylist_tab_size;
00134 UINT32 fld_tab_size;
00135 UINT32 arb_tab_size;
00136 UINT32 tcon_tab_size;
00137 UINT32 inito_tab_size;
00138 UINT32 initv_tab_size;
00139 UINT32 st_attr_tab_size;
00140
00141 char *symstr_tab;
00142 char *tconstr_tab;
00143 PU *pu_tab;
00144 ST *st_tab;
00145 TY *ty_tab;
00146 TYLIST *tylist_tab;
00147 FLD *fld_tab;
00148 ARB *arb_tab;
00149 TCON *tcon_tab;
00150 INITO *inito_tab;
00151 INITV *initv_tab;
00152 ST_ATTR *st_attr_tab;
00153 };
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163 template <class MAP>
00164 struct IDX_MAP
00165 {
00166 MAP map;
00167
00168 typedef typename MAP::allocator_type allocator_type;
00169 typedef typename MAP::value_type value_type;
00170
00171 IDX_MAP (mUINT32 size = 0, allocator_type a = allocator_type()) :
00172 map (size, value_type(), a) {}
00173
00174 mUINT32 operator[] (mUINT32 old_idx) const {
00175 return map[old_idx];
00176 }
00177
00178 void set_map (mUINT32 old_idx, mUINT32 new_idx) {
00179 map[old_idx] = new_idx;
00180 }
00181
00182 };
00183
00184
00185
00186
00187
00188
00189
00190 struct ST_IDX_MAP
00191 {
00192 IPC_IDX_VECTOR map_;
00193
00194 typedef IPC_IDX_VECTOR::allocator_type allocator_type;
00195
00196 ST_IDX_MAP (mUINT32 size, allocator_type alloc) :
00197 map_ (size, UNINITIALIZED_INDEX, alloc) {}
00198
00199 ST_IDX operator[] (ST_IDX old_idx) const {
00200 UINT idx = ST_IDX_index(old_idx);
00201 Is_True(ST_IDX_level(old_idx) == GLOBAL_SYMTAB,
00202 ("ST_IDX_MAP used for non-global symbol %ld:%ld",
00203 ST_IDX_level(old_idx), idx));
00204 Is_True(idx < map_.size(),
00205 ("ST_IDX_MAP: Index %ld out of range. (Max = %ld)",
00206 idx, map_.size() - 1));
00207 return map_[idx];
00208 }
00209
00210 void set_map(ST_IDX old_idx, ST_IDX new_idx) {
00211 Is_True (ST_IDX_level (old_idx) == GLOBAL_SYMTAB,
00212 ("ST_IDX_MAP is for global symbols only"));
00213 UINT idx = ST_IDX_index(old_idx);
00214 map_[idx] = new_idx;
00215 }
00216
00217 };
00218
00219
00220
00221
00222
00223
00224
00225
00226 typedef UINT32 TY_INDEX;
00227
00228
00229 enum TY_MERGE_FLAG
00230 {
00231 TY_INDEX_IS_MERGING = TY_RESTRICT,
00232 };
00233
00234 inline TY_IDX
00235 Replace_TY_IDX_index (TY_IDX orig_idx, TY_IDX new_idx)
00236 {
00237 return (new_idx & ~0xff) | (orig_idx & 0xff);
00238 }
00239
00240
00241 inline TY_IDX
00242 make_TY_IDX (TY_INDEX idx, TY_IDX attributes)
00243 {
00244 return (idx << 8) | (attributes & 0xff);
00245 }
00246
00247
00248 struct TY_IDX_MAP
00249 {
00250 IPC_IDX_VECTOR map_;
00251
00252 typedef IPC_IDX_VECTOR::allocator_type allocator_type;
00253
00254 TY_IDX_MAP (mUINT32 size, allocator_type alloc) :
00255 map_ (size, UNINITIALIZED_INDEX, alloc) {}
00256
00257 TY_IDX operator[] (TY_IDX old_idx) const {
00258 TY_IDX new_idx = map_[TY_IDX_index (old_idx)];
00259 return Replace_TY_IDX_index (old_idx, new_idx);
00260 }
00261
00262 void set_map(TY_INDEX old_idx, TY_IDX new_idx) {
00263
00264
00265 map_[old_idx] = new_idx & ~0xff;
00266 }
00267
00268 void set_is_merging (TY_INDEX old_idx) {
00269 map_[old_idx] |= TY_INDEX_IS_MERGING;
00270 }
00271
00272 BOOL is_merging (TY_INDEX old_idx) {
00273 return map_[old_idx] & TY_INDEX_IS_MERGING;
00274 }
00275
00276 void clear_all_index_flags (TY_INDEX old_idx) {
00277 map_[old_idx] &= ~0xff;
00278 }
00279 };
00280
00281
00282 typedef STR_IDX_MAP SYMSTR_IDX_MAP;
00283 typedef IDX_MAP<IPC_IDX_VECTOR> TCON_IDX_MAP;
00284 typedef IDX_MAP<IPC_IDX_VECTOR> INITV_IDX_MAP;
00285
00286 struct IPC_GLOBAL_IDX_MAP
00287 {
00288 SYMSTR_IDX_MAP sym_str;
00289 ST_IDX_MAP st;
00290 TY_IDX_MAP ty;
00291 TCON_IDX_MAP tcon;
00292 INITV_IDX_MAP initv;
00293
00294 IPC_GLOBAL_IDX_MAP (UINT32 st_size, UINT32 ty_size, UINT32 tcon_size,
00295 UINT32 initv_size, MEM_POOL *pool) :
00296 sym_str (0, __new_hash::hash<STR_IDX>(), std::equal_to<STR_IDX> (),
00297 SYMSTR_IDX_MAP::allocator_type (pool)),
00298 st (st_size, ST_IDX_MAP::allocator_type (pool)),
00299 ty (ty_size, TY_IDX_MAP::allocator_type (pool)),
00300 tcon (tcon_size, TCON_IDX_MAP::allocator_type (pool)),
00301 initv (initv_size, INITV_IDX_MAP::allocator_type (pool)) {}
00302
00303 };
00304
00305 typedef hash_map<ST_IDX, INITO_IDX> ST_TO_INITO_MAP;
00306 extern ST_TO_INITO_MAP ST_To_INITO_Map;
00307
00308
00309
00310
00311
00312
00313 typedef pair<const TY*, mUINT64> BLOCK_ELEMENT_DESC;
00314
00315 struct block_element_compare
00316 {
00317 bool operator() (const BLOCK_ELEMENT_DESC& desc1,
00318 const BLOCK_ELEMENT_DESC& desc2) const {
00319 if (desc1.second != desc2.second)
00320 return desc1.second < desc2.second;
00321 if (TY_size (*desc1.first) != TY_size (*desc2.first))
00322 return TY_size (*desc1.first) < TY_size (*desc2.first);
00323 return desc1.first < desc2.first;
00324 }
00325 };
00326
00327 typedef std::map<const BLOCK_ELEMENT_DESC, ST_IDX, block_element_compare,
00328 mempool_allocator< std::pair<const BLOCK_ELEMENT_DESC, ST_IDX> > > BLOCK_ELEMENTS;
00329 typedef hash_map<ST_IDX, BLOCK_ELEMENTS*, __gnu_cxx::hash<ST_IDX>, std::equal_to<ST_IDX>,
00330 mempool_allocator<BLOCK_ELEMENTS*> > COMMON_BLOCK_ELEMENTS_MAP;
00331
00332 extern COMMON_BLOCK_ELEMENTS_MAP *Common_Block_Elements_Map;
00333
00334
00335
00336
00337
00338 struct AUX_ST
00339 {
00340 mUINT32 flags;
00341 mUINT32 refcount;
00342 mUINT32 modcount;
00343
00344 AUX_ST () : flags (0), refcount (0), modcount (0) {}
00345
00346 void construct () {
00347 new (this) AUX_ST ();
00348 }
00349 };
00350
00351 inline BOOL
00352 AUX_ST_flags (const AUX_ST& aux_st, UINT32 f) {
00353 return aux_st.flags & f;
00354 }
00355 inline void
00356 Set_AUX_ST_flags (AUX_ST& aux_st, UINT32 f) {
00357 aux_st.flags |= f;
00358 }
00359 inline void
00360 Clear_AUX_ST_flags (AUX_ST& aux_st, UINT32 f) {
00361 aux_st.flags &= ~f;
00362 }
00363
00364 inline UINT32
00365 AUX_ST_refcount (const AUX_ST& aux_st) {
00366 return aux_st.refcount;
00367 }
00368 inline void
00369 Inc_AUX_ST_refcount (AUX_ST& aux_st, INT32 count) {
00370 aux_st.refcount += count;
00371 }
00372
00373 inline UINT32
00374 AUX_ST_modcount (const AUX_ST& aux_st) {
00375 return aux_st.modcount;
00376 }
00377 inline void
00378 Inc_AUX_ST_modcount (AUX_ST& aux_st, INT32 count) {
00379 aux_st.modcount += count;
00380 }
00381
00382
00383
00384 typedef RELATED_SEGMENTED_ARRAY<AUX_ST,1024> AUX_ST_TAB;
00385 extern AUX_ST_TAB Aux_St_Tab;
00386
00387 struct AUX_ST_TABLE
00388 {
00389 AUX_ST& operator[] (ST_IDX st_idx) const {
00390 Is_True (ST_IDX_level(st_idx) == GLOBAL_SYMTAB, ("Invalid st_idx"));
00391 return Aux_St_Tab[ST_IDX_index (st_idx)];
00392 }
00393
00394 };
00395
00396 extern AUX_ST_TABLE Aux_St_Table;
00397
00398 struct AUX_PU
00399 {
00400 NODE_INDEX node;
00401 IP_FILE_HDR* file_hdr;
00402
00403
00404 AUX_PU () : node (INVALID_NODE_INDEX), file_hdr (NULL) {}
00405
00406 void construct () {
00407 new (this) AUX_PU ();
00408 }
00409 };
00410
00411 inline void
00412 Set_AUX_PU_node (AUX_PU& pu, NODE_INDEX node)
00413 {
00414 pu.node = node;
00415 }
00416 inline NODE_INDEX
00417 AUX_PU_node (const AUX_PU& pu)
00418 {
00419 return pu.node;
00420 }
00421
00422 inline void
00423 Set_AUX_PU_file_hdr (AUX_PU& pu, IP_FILE_HDR* file_hdr)
00424 {
00425 pu.file_hdr = file_hdr;
00426 }
00427 inline IP_FILE_HDR*
00428 AUX_PU_file_hdr (const AUX_PU& pu)
00429 {
00430 return pu.file_hdr;
00431 }
00432
00433
00434
00435 typedef SEGMENTED_ARRAY<AUX_PU,256> AUX_PU_TAB;
00436 extern AUX_PU_TAB Aux_Pu_Table;
00437
00438
00439 extern void Initialize_Auxiliary_Tables ();
00440
00441 extern void Clear_Extra_Auxiliary_Tables ();
00442
00443 extern void Clear_Common_Block_Element_Map ();
00444
00445 extern IPC_GLOBAL_IDX_MAP *
00446 IPC_merge_global_tab(const IPC_GLOBAL_TABS &original_tabs,
00447 IP_FILE_HDR& hdr, MEM_POOL* mempool);
00448
00449 extern void
00450 Update_reference_count (ST* st, INT32 refcount, INT32 modcount,
00451 BOOL is_cmod);
00452
00453 extern void
00454 Print_AUX_ST_flags ( FILE *fp, const mUINT32 flags );
00455
00456 extern void
00457 Verify_Common_Block_Layout ();
00458
00459 extern void
00460 Synch_ST_flags (ST& merged_st, const ST& original_st);
00461
00462 #endif
00463 #endif