Skip to content

Commit 9f1cc44

Browse files
authored
Use uint64_t for debuginfo address differences/slide (#60179)
Replace all uses of `ptrdiff_t slide` and `int64_t slide` with `uint64_t`. If a JITted object is ever assigned an address in the upper half of the address space on a platform with `sizeof(char *) = 4`, which is quite common on 32-bit Linux, the following can happen: In JITDebugInfoRegistry::registerJITObject, `SectionAddr - SectionLoadAddr` is computed in uint64_t (ok), then cast to ptrdiff_t (two's complement of the uint64_t version mod 2^32). This is apparently implementation-defined behaviour rather than undefined. Say SectionAddr = 0x1000UL, SectionLoadAddr = 0xe93b2000UL and size_t pointer = 0xe93b20abU. ``` (ptrdiff_t)(SectionAddr - SectionLoadAddr) == (ptrdiff_t)0xffffffff16c4f000 == 382005248 ``` jl_DI_for_fptr implicitly converts the ptrdiff_t to int64_t: ``` (int64_t)382005248 == 382005248L ``` lookup_pointer adds `size_t pointer` to `int64_t slide`. Both are converted to int64_t because it can represent every size_t: ``` (int64_t)0xe93b20abU + 382005248L == 3912966315L + 382005248L == 4294971563L ``` This is converted back to uint64_t by makeAddress, resulting in an address other than the 0x10ab we expected: ``` (uint64_t)4294971563L == 0x1000010abUL ``` It is easier to use uint64_t everywhere we need a difference, since they avoid the problem of losing upper bits after sign extension and avoid weird UB from signed overflow. Cherry-picked from #60031. [1] https://buildkite.com/julialang/julia-master/builds/52196/steps/canvas?sid=019a9d6f-14a6-4ffc-be19-f2f835d1e719
1 parent 5444ac0 commit 9f1cc44

File tree

4 files changed

+18
-18
lines changed

4 files changed

+18
-18
lines changed

src/debug-registry.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
typedef struct {
1212
const llvm::object::ObjectFile *obj;
1313
llvm::DIContext *ctx;
14-
int64_t slide;
14+
uint64_t slide;
1515
std::map<uintptr_t, StringRef, std::greater<size_t>> *symbolmap;
1616
} jl_object_file_entry_t;
1717

@@ -112,7 +112,7 @@ class JITDebugInfoRegistry
112112
struct SectionInfo {
113113
LazyObjectInfo *object;
114114
size_t SectionSize;
115-
ptrdiff_t slide;
115+
uint64_t slide;
116116
uint64_t SectionIndex;
117117
SectionInfo() = delete;
118118
~SectionInfo() JL_NOTSAFEPOINT = default;

src/debuginfo.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ void JITDebugInfoRegistry::registerJITObject(const object::ObjectFile &Object,
395395
objectmap.insert(std::pair{SectionLoadAddr, SectionInfo{
396396
ObjectCopy,
397397
(size_t)SectionSize,
398-
(ptrdiff_t)(SectionAddr - SectionLoadAddr),
398+
SectionAddr - SectionLoadAddr,
399399
Section->getIndex()
400400
}});
401401
});
@@ -448,7 +448,7 @@ static std::pair<char *, bool> jl_demangle(const char *name) JL_NOTSAFEPOINT
448448
// func_name and file_name are either NULL or malloc'd pointers
449449
static int lookup_pointer(
450450
object::SectionRef Section, DIContext *context,
451-
jl_frame_t **frames, size_t pointer, int64_t slide,
451+
jl_frame_t **frames, size_t pointer, uint64_t slide,
452452
bool demangle, bool noInline) JL_NOTSAFEPOINT
453453
{
454454
// This function is not allowed to reference any TLS variables
@@ -719,7 +719,7 @@ static inline void ignoreError(T &err) JL_NOTSAFEPOINT
719719
}
720720

721721
static void get_function_name_and_base(llvm::object::SectionRef Section, std::map<uintptr_t, StringRef, std::greater<size_t>> *symbolmap,
722-
size_t pointer, int64_t slide, bool inimage,
722+
size_t pointer, uint64_t slide, bool inimage,
723723
void **saddr, char **name, bool untrusted_dladdr) JL_NOTSAFEPOINT
724724
{
725725
bool needs_saddr = saddr && (!*saddr || untrusted_dladdr);
@@ -1011,14 +1011,14 @@ static jl_object_file_entry_t find_object_file(uint64_t fbase, StringRef fname)
10111011
}
10121012
}
10131013

1014-
int64_t slide = 0;
1014+
uint64_t slide = 0;
10151015
if (auto *OF = dyn_cast<const object::COFFObjectFile>(debugobj)) {
10161016
if (!iswindows) // the COFF parser accepts some garbage inputs (like empty files) that the other parsers correctly reject, so we can end up here even when we should not
10171017
return entry;
10181018
slide = OF->getImageBase() - fbase;
10191019
}
10201020
else {
1021-
slide = -(int64_t)fbase;
1021+
slide = -fbase;
10221022
}
10231023

10241024
auto context = DWARFContext::create(*debugobj).release();
@@ -1051,7 +1051,7 @@ static object::SectionRef getModuleSectionForAddress(const object::ObjectFile *o
10511051
}
10521052

10531053

1054-
bool jl_dylib_DI_for_fptr(size_t pointer, object::SectionRef *Section, int64_t *slide, llvm::DIContext **context,
1054+
bool jl_dylib_DI_for_fptr(size_t pointer, object::SectionRef *Section, uint64_t *slide, llvm::DIContext **context,
10551055
bool onlyImage, bool *isImage, uint64_t *_fbase, void **saddr, char **name, char **filename) JL_NOTSAFEPOINT
10561056
{
10571057
*Section = object::SectionRef();
@@ -1190,7 +1190,7 @@ static int jl_getDylibFunctionInfo(jl_frame_t **frames, size_t pointer, int skip
11901190
#endif
11911191
object::SectionRef Section;
11921192
llvm::DIContext *context = NULL;
1193-
int64_t slide;
1193+
uint64_t slide;
11941194
bool isImage;
11951195
void *saddr;
11961196
uint64_t fbase;
@@ -1222,7 +1222,7 @@ static int jl_getDylibFunctionInfo(jl_frame_t **frames, size_t pointer, int skip
12221222
return lookup_pointer(Section, context, frames, pointer, slide, isImage, noInline);
12231223
}
12241224

1225-
int jl_DI_for_fptr(uint64_t fptr, uint64_t *symsize, int64_t *slide,
1225+
int jl_DI_for_fptr(uint64_t fptr, uint64_t *symsize, uint64_t *slide,
12261226
object::SectionRef *Section, llvm::DIContext **context) JL_NOTSAFEPOINT
12271227
{
12281228
int found = 0;
@@ -1283,7 +1283,7 @@ extern "C" JL_DLLEXPORT_CODEGEN int jl_getFunctionInfo_impl(jl_frame_t **frames_
12831283

12841284
llvm::DIContext *context = nullptr;
12851285
object::SectionRef Section;
1286-
int64_t slide;
1286+
uint64_t slide;
12871287
uint64_t symsize;
12881288
if (jl_DI_for_fptr(pointer, &symsize, &slide, &Section, &context)) {
12891289
frames[0].ci = getJITDebugRegistry().lookupCodeInstance(pointer);

src/debuginfo.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
// Declarations for debuginfo.cpp
44
void jl_jit_add_bytes(size_t bytes) JL_NOTSAFEPOINT;
55

6-
int jl_DI_for_fptr(uint64_t fptr, uint64_t *symsize, int64_t *slide,
6+
int jl_DI_for_fptr(uint64_t fptr, uint64_t *symsize, uint64_t *slide,
77
llvm::object::SectionRef *Section, llvm::DIContext **context) JL_NOTSAFEPOINT;
88

9-
bool jl_dylib_DI_for_fptr(size_t pointer, llvm::object::SectionRef *Section, int64_t *slide, llvm::DIContext **context,
9+
bool jl_dylib_DI_for_fptr(size_t pointer, llvm::object::SectionRef *Section, uint64_t *slide, llvm::DIContext **context,
1010
bool onlyImage, bool *isImage, uint64_t* fbase, void **saddr, char **name, char **filename) JL_NOTSAFEPOINT;
1111

1212
static object::SectionedAddress makeAddress(

src/disasm.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,7 @@ jl_value_t *jl_dump_function_ir_impl(jl_llvmf_dump_t *dump, char strip_ir_metada
543543
}
544544

545545
static void jl_dump_asm_internal(
546-
uintptr_t Fptr, size_t Fsize, int64_t slide,
546+
uintptr_t Fptr, size_t Fsize, uint64_t slide,
547547
object::SectionRef Section,
548548
DIContext *di_ctx,
549549
raw_ostream &rstream,
@@ -593,7 +593,7 @@ jl_value_t *jl_dump_fptr_asm_impl(uint64_t fptr, char emit_mc, const char* asm_v
593593

594594
// Find debug info (line numbers) to print alongside
595595
object::SectionRef Section;
596-
int64_t slide = 0;
596+
uint64_t slide = 0;
597597
uint64_t symsize = 0;
598598
llvm::DIContext *context = NULL;
599599
if (!jl_DI_for_fptr(fptr, &symsize, &slide, &Section, &context)) {
@@ -646,9 +646,9 @@ class SymbolTable {
646646
int Pass;
647647
const object::ObjectFile *object;
648648
uint64_t ip; // virtual instruction pointer of the current instruction
649-
int64_t slide;
649+
uint64_t slide;
650650
public:
651-
SymbolTable(MCContext &Ctx, const object::ObjectFile *object, int64_t slide, const FuncMCView &MemObj) JL_NOTSAFEPOINT
651+
SymbolTable(MCContext &Ctx, const object::ObjectFile *object, uint64_t slide, const FuncMCView &MemObj) JL_NOTSAFEPOINT
652652
: Ctx(Ctx), MemObj(MemObj), object(object), ip(0), slide(slide) {}
653653
~SymbolTable() JL_NOTSAFEPOINT = default;
654654
const FuncMCView &getMemoryObject() const JL_NOTSAFEPOINT { return MemObj; }
@@ -851,7 +851,7 @@ std::string rawCodeComment(const llvm::ArrayRef<uint8_t>& Memory, const llvm::Tr
851851
}
852852

853853
static void jl_dump_asm_internal(
854-
uintptr_t Fptr, size_t Fsize, int64_t slide,
854+
uintptr_t Fptr, size_t Fsize, uint64_t slide,
855855
object::SectionRef Section,
856856
DIContext *di_ctx,
857857
raw_ostream &rstream,

0 commit comments

Comments
 (0)