VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/ldr/ldrELF.cpp@ 89208

Last change on this file since 89208 was 85501, checked in by vboxsync, 4 years ago

IPRT/ldrELF: Early support for loading ET_DYN images. Current code is a bit cumbersome as it approaches it from the ET_REL/sections perspective rather than using program headers and the dynamic section. bugref:9801

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 6.5 KB
Line 
1/* $Id: ldrELF.cpp 85501 2020-07-29 09:10:35Z vboxsync $ */
2/** @file
3 * IPRT - Binary Image Loader, Executable and Linker Format (ELF).
4 */
5
6/*
7 * Copyright (C) 2006-2020 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#define LOG_GROUP RTLOGGROUP_LDR
32#include <iprt/ldr.h>
33#include "internal/iprt.h"
34
35#include <iprt/alloc.h>
36#include <iprt/assert.h>
37#include <iprt/dbg.h>
38#include <iprt/string.h>
39#include <iprt/log.h>
40#include <iprt/err.h>
41#include <iprt/formats/elf32.h>
42#include <iprt/formats/elf64.h>
43#include <iprt/formats/elf-i386.h>
44#include <iprt/formats/elf-amd64.h>
45#include "internal/ldr.h"
46#include "internal/dbgmod.h"
47
48
49
50/*********************************************************************************************************************************
51* Defined Constants And Macros *
52*********************************************************************************************************************************/
53/** Finds an ELF symbol table string. */
54#define ELF_STR(pHdrs, iStr) ((pHdrs)->Rel.pStr + (iStr))
55/** Finds an ELF symbol table string. */
56#define ELF_DYN_STR(pHdrs, iStr) ((pHdrs)->Dyn.pStr + (iStr))
57/** Finds an ELF section header string. */
58#define ELF_SH_STR(pHdrs, iStr) ((pHdrs)->pShStr + (iStr))
59
60
61
62/*********************************************************************************************************************************
63* Internal Functions *
64*********************************************************************************************************************************/
65#ifdef LOG_ENABLED
66static const char *rtldrElfGetShdrType(uint32_t iType);
67static const char *rtldrElfGetPhdrType(uint32_t iType);
68#endif
69
70
71/* Select ELF mode and include the template. */
72#define ELF_MODE 32
73#define Elf_Reloc Elf_Rel
74#include "ldrELFRelocatable.cpp.h"
75#undef ELF_MODE
76#undef Elf_Reloc
77
78
79#define ELF_MODE 64
80#define Elf_Reloc Elf_Rela
81#include "ldrELFRelocatable.cpp.h"
82#undef ELF_MODE
83#undef Elf_Reloc
84
85
86#ifdef LOG_ENABLED
87
88/**
89 * Gets the section type.
90 *
91 * @returns Pointer to read only string.
92 * @param iType The section type index.
93 */
94static const char *rtldrElfGetShdrType(uint32_t iType)
95{
96 switch (iType)
97 {
98 RT_CASE_RET_STR(SHT_NULL);
99 RT_CASE_RET_STR(SHT_PROGBITS);
100 RT_CASE_RET_STR(SHT_SYMTAB);
101 RT_CASE_RET_STR(SHT_STRTAB);
102 RT_CASE_RET_STR(SHT_RELA);
103 RT_CASE_RET_STR(SHT_HASH);
104 RT_CASE_RET_STR(SHT_DYNAMIC);
105 RT_CASE_RET_STR(SHT_NOTE);
106 RT_CASE_RET_STR(SHT_NOBITS);
107 RT_CASE_RET_STR(SHT_REL);
108 RT_CASE_RET_STR(SHT_SHLIB);
109 RT_CASE_RET_STR(SHT_DYNSYM);
110 default:
111 return "";
112 }
113}
114
115/**
116 * Gets the program header type.
117 *
118 * @returns Pointer to read only string.
119 * @param iType The section type index.
120 */
121static const char *rtldrElfGetPhdrType(uint32_t iType)
122{
123 switch (iType)
124 {
125 RT_CASE_RET_STR(PT_NULL);
126 RT_CASE_RET_STR(PT_LOAD);
127 RT_CASE_RET_STR(PT_DYNAMIC);
128 RT_CASE_RET_STR(PT_INTERP);
129 RT_CASE_RET_STR(PT_NOTE);
130 RT_CASE_RET_STR(PT_SHLIB);
131 RT_CASE_RET_STR(PT_PHDR);
132 RT_CASE_RET_STR(PT_TLS);
133 RT_CASE_RET_STR(PT_GNU_EH_FRAME);
134 RT_CASE_RET_STR(PT_GNU_STACK);
135 RT_CASE_RET_STR(PT_GNU_RELRO);
136 RT_CASE_RET_STR(PT_GNU_PROPERTY);
137 default:
138 return "";
139 }
140}
141
142#endif /* LOG_ENABLED*/
143
144
145/**
146 * Open an ELF image.
147 *
148 * @returns iprt status code.
149 * @param pReader The loader reader instance which will provide the raw image bits.
150 * @param fFlags Reserved, MBZ.
151 * @param enmArch Architecture specifier.
152 * @param phLdrMod Where to store the handle.
153 * @param pErrInfo Where to return extended error information. Optional.
154 */
155DECLHIDDEN(int) rtldrELFOpen(PRTLDRREADER pReader, uint32_t fFlags, RTLDRARCH enmArch, PRTLDRMOD phLdrMod, PRTERRINFO pErrInfo)
156{
157 const char *pszLogName = pReader->pfnLogName(pReader); NOREF(pszLogName);
158
159 /*
160 * Read the ident to decide if this is 32-bit or 64-bit
161 * and worth dealing with.
162 */
163 uint8_t e_ident[EI_NIDENT];
164 int rc = pReader->pfnRead(pReader, &e_ident, sizeof(e_ident), 0);
165 if (RT_FAILURE(rc))
166 return rc;
167
168 if ( e_ident[EI_MAG0] != ELFMAG0
169 || e_ident[EI_MAG1] != ELFMAG1
170 || e_ident[EI_MAG2] != ELFMAG2
171 || e_ident[EI_MAG3] != ELFMAG3
172 || ( e_ident[EI_CLASS] != ELFCLASS32
173 && e_ident[EI_CLASS] != ELFCLASS64)
174 )
175 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_BAD_EXE_FORMAT,
176 "%s: Unsupported/invalid ident %.*Rhxs", pszLogName, sizeof(e_ident), e_ident);
177
178 if (e_ident[EI_DATA] != ELFDATA2LSB)
179 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_LDRELF_ODD_ENDIAN,
180 "%s: ELF endian %x is unsupported", pszLogName, e_ident[EI_DATA]);
181
182 if (e_ident[EI_CLASS] == ELFCLASS32)
183 rc = rtldrELF32Open(pReader, fFlags, enmArch, phLdrMod, pErrInfo);
184 else
185 rc = rtldrELF64Open(pReader, fFlags, enmArch, phLdrMod, pErrInfo);
186 return rc;
187}
188
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette