blob: 261d8637e3442a7950c22f9084a5c2537808ee6b [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "dynlink.h"
__NO_SAFESTACK NO_ASAN static inline void apply_relr(ElfW(Addr) base,
const ElfW(Addr)* relr,
size_t relrsz) {
const size_t nrelr = relrsz / sizeof(relr[0]);
size_t i = 0;
while (i < nrelr) {
ElfW(Addr)* addr = (void*)(base + relr[i++]);
*addr++ += base;
while (i < nrelr && (relr[i] & 1)) {
// Each bitmask word covers the next 63 possible relocations.
// Each bit is one if run[bit] should be relocated.
ElfW(Addr)* run = addr;
addr += (sizeof(relr[0]) * CHAR_BIT) - 1;
int skip;
for (ElfW(Addr) bitmask = relr[i++] >> 1;
bitmask != 0;
bitmask >>= skip) {
skip = __builtin_ctzl(bitmask) + 1;
run += skip;
run[-1] += base;
}
}
}
}