mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-23 18:26:15 +00:00
Merge autoland to mozilla-central. a=merge
This commit is contained in:
commit
4515e2b048
@ -391,17 +391,18 @@ ContentPrincipal::SetDomain(nsIURI* aDomain)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static nsresult
|
static nsresult
|
||||||
GetBaseDomainHelper(const nsCOMPtr<nsIURI>& aCodebase,
|
GetSpecialBaseDomain(const nsCOMPtr<nsIURI>& aCodebase,
|
||||||
bool* aHasBaseDomain,
|
bool* aHandled,
|
||||||
nsACString& aBaseDomain)
|
nsACString& aBaseDomain)
|
||||||
{
|
{
|
||||||
*aHasBaseDomain = false;
|
*aHandled = false;
|
||||||
|
|
||||||
// For a file URI, we return the file path.
|
// For a file URI, we return the file path.
|
||||||
if (NS_URIIsLocalFile(aCodebase)) {
|
if (NS_URIIsLocalFile(aCodebase)) {
|
||||||
nsCOMPtr<nsIURL> url = do_QueryInterface(aCodebase);
|
nsCOMPtr<nsIURL> url = do_QueryInterface(aCodebase);
|
||||||
|
|
||||||
if (url) {
|
if (url) {
|
||||||
|
*aHandled = true;
|
||||||
return url->GetFilePath(aBaseDomain);
|
return url->GetFilePath(aBaseDomain);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -415,52 +416,84 @@ GetBaseDomainHelper(const nsCOMPtr<nsIURI>& aCodebase,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (hasNoRelativeFlag) {
|
if (hasNoRelativeFlag) {
|
||||||
|
*aHandled = true;
|
||||||
return aCodebase->GetSpec(aBaseDomain);
|
return aCodebase->GetSpec(aBaseDomain);
|
||||||
}
|
}
|
||||||
|
|
||||||
*aHasBaseDomain = true;
|
|
||||||
|
|
||||||
// For everything else, we ask the TLD service via
|
|
||||||
// the ThirdPartyUtil.
|
|
||||||
nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil =
|
|
||||||
do_GetService(THIRDPARTYUTIL_CONTRACTID);
|
|
||||||
if (thirdPartyUtil) {
|
|
||||||
return thirdPartyUtil->GetBaseDomain(aCodebase, aBaseDomain);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
ContentPrincipal::GetBaseDomain(nsACString& aBaseDomain)
|
ContentPrincipal::GetBaseDomain(nsACString& aBaseDomain)
|
||||||
{
|
{
|
||||||
bool hasBaseDomain;
|
// Handle some special URIs first.
|
||||||
return GetBaseDomainHelper(mCodebase, &hasBaseDomain, aBaseDomain);
|
bool handled;
|
||||||
|
nsresult rv = GetSpecialBaseDomain(mCodebase, &handled, aBaseDomain);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
if (handled) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For everything else, we ask the TLD service via the ThirdPartyUtil.
|
||||||
|
nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil =
|
||||||
|
do_GetService(THIRDPARTYUTIL_CONTRACTID);
|
||||||
|
if (!thirdPartyUtil) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return thirdPartyUtil->GetBaseDomain(mCodebase, aBaseDomain);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
ContentPrincipal::GetSiteOrigin(nsACString& aSiteOrigin)
|
ContentPrincipal::GetSiteOrigin(nsACString& aSiteOrigin)
|
||||||
{
|
{
|
||||||
// Determine our base domain.
|
// Handle some special URIs first.
|
||||||
bool hasBaseDomain;
|
|
||||||
nsAutoCString baseDomain;
|
nsAutoCString baseDomain;
|
||||||
nsresult rv = GetBaseDomainHelper(mCodebase, &hasBaseDomain, baseDomain);
|
bool handled;
|
||||||
|
nsresult rv = GetSpecialBaseDomain(mCodebase, &handled, baseDomain);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
if (!hasBaseDomain) {
|
if (handled) {
|
||||||
// This is a special URI ("file:", "about:", "view-source:", etc). Just
|
// This is a special URI ("file:", "about:", "view-source:", etc). Just
|
||||||
// return the origin.
|
// return the origin.
|
||||||
return GetOrigin(aSiteOrigin);
|
return GetOrigin(aSiteOrigin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For everything else, we ask the TLD service. Note that, unlike in
|
||||||
|
// GetBaseDomain, we don't use ThirdPartyUtil.getBaseDomain because if the
|
||||||
|
// host is an IP address that returns the raw address and we can't use it with
|
||||||
|
// SetHost below because SetHost expects '[' and ']' around IPv6 addresses.
|
||||||
|
// See bug 1491728.
|
||||||
|
nsCOMPtr<nsIEffectiveTLDService> tldService =
|
||||||
|
do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID);
|
||||||
|
if (!tldService) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool gotBaseDomain = false;
|
||||||
|
rv = tldService->GetBaseDomain(mCodebase, 0, baseDomain);
|
||||||
|
if (NS_SUCCEEDED(rv)) {
|
||||||
|
gotBaseDomain = true;
|
||||||
|
} else {
|
||||||
|
// If this is an IP address or something like "localhost", we just continue
|
||||||
|
// with gotBaseDomain = false.
|
||||||
|
if (rv != NS_ERROR_HOST_IS_IP_ADDRESS &&
|
||||||
|
rv != NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE: Calling `SetHostPort` with a portless domain is insufficient to clear
|
// NOTE: Calling `SetHostPort` with a portless domain is insufficient to clear
|
||||||
// the port, so an extra `SetPort` call has to be made.
|
// the port, so an extra `SetPort` call has to be made.
|
||||||
nsCOMPtr<nsIURI> siteUri;
|
nsCOMPtr<nsIURI> siteUri;
|
||||||
rv = NS_MutateURI(mCodebase)
|
NS_MutateURI mutator(mCodebase);
|
||||||
.SetUserPass(EmptyCString())
|
mutator.SetUserPass(EmptyCString())
|
||||||
.SetPort(-1)
|
.SetPort(-1);
|
||||||
.SetHostPort(baseDomain)
|
if (gotBaseDomain) {
|
||||||
.Finalize(siteUri);
|
mutator.SetHost(baseDomain);
|
||||||
|
}
|
||||||
|
rv = mutator.Finalize(siteUri);
|
||||||
MOZ_ASSERT(NS_SUCCEEDED(rv), "failed to create siteUri");
|
MOZ_ASSERT(NS_SUCCEEDED(rv), "failed to create siteUri");
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
@ -374,6 +374,11 @@ Animation::UpdatePlaybackRate(double aPlaybackRate)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Calculate the play state using the existing playback rate since below we
|
||||||
|
// want to know if the animation is _currently_ finished or not, not whether
|
||||||
|
// it _will_ be finished.
|
||||||
|
AnimationPlayState playState = PlayState();
|
||||||
|
|
||||||
mPendingPlaybackRate = Some(aPlaybackRate);
|
mPendingPlaybackRate = Some(aPlaybackRate);
|
||||||
|
|
||||||
// If we already have a pending task, there is nothing more to do since the
|
// If we already have a pending task, there is nothing more to do since the
|
||||||
@ -384,7 +389,6 @@ Animation::UpdatePlaybackRate(double aPlaybackRate)
|
|||||||
|
|
||||||
AutoMutationBatchForAnimation mb(*this);
|
AutoMutationBatchForAnimation mb(*this);
|
||||||
|
|
||||||
AnimationPlayState playState = PlayState();
|
|
||||||
if (playState == AnimationPlayState::Idle ||
|
if (playState == AnimationPlayState::Idle ||
|
||||||
playState == AnimationPlayState::Paused) {
|
playState == AnimationPlayState::Paused) {
|
||||||
// We are either idle or paused. In either case we can apply the pending
|
// We are either idle or paused. In either case we can apply the pending
|
||||||
@ -457,9 +461,10 @@ Animation::PlayState() const
|
|||||||
return AnimationPlayState::Paused;
|
return AnimationPlayState::Paused;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double playbackRate = CurrentOrPendingPlaybackRate();
|
||||||
if (!currentTime.IsNull() &&
|
if (!currentTime.IsNull() &&
|
||||||
((mPlaybackRate > 0.0 && currentTime.Value() >= EffectEnd()) ||
|
((playbackRate > 0.0 && currentTime.Value() >= EffectEnd()) ||
|
||||||
(mPlaybackRate < 0.0 && currentTime.Value() <= TimeDuration()))) {
|
(playbackRate < 0.0 && currentTime.Value() <= TimeDuration()))) {
|
||||||
return AnimationPlayState::Finished;
|
return AnimationPlayState::Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1564,7 +1564,7 @@ WebRenderBridgeParent::CompositeToTarget(gfx::DrawTarget* aTarget, const gfx::In
|
|||||||
MOZ_ASSERT(aTarget == nullptr);
|
MOZ_ASSERT(aTarget == nullptr);
|
||||||
MOZ_ASSERT(aRect == nullptr);
|
MOZ_ASSERT(aRect == nullptr);
|
||||||
|
|
||||||
AUTO_PROFILER_TRACING("Paint", "CompositeToTraget");
|
AUTO_PROFILER_TRACING("Paint", "CompositeToTarget");
|
||||||
if (mPaused || !mReceivedDisplayList) {
|
if (mPaused || !mReceivedDisplayList) {
|
||||||
mPreviousFrameTimeStamp = TimeStamp();
|
mPreviousFrameTimeStamp = TimeStamp();
|
||||||
return;
|
return;
|
||||||
|
@ -22,8 +22,7 @@ test(t => {
|
|||||||
+ ' and no pending tasks')
|
+ ' and no pending tasks')
|
||||||
|
|
||||||
test(t => {
|
test(t => {
|
||||||
const div = createDiv(t);
|
const animation = createDiv(t).animate({}, 100 * MS_PER_SEC);
|
||||||
const animation = div.animate({}, 100 * MS_PER_SEC);
|
|
||||||
|
|
||||||
animation.pause();
|
animation.pause();
|
||||||
|
|
||||||
@ -134,8 +133,7 @@ test(t => {
|
|||||||
+ ' current time = 0');
|
+ ' current time = 0');
|
||||||
|
|
||||||
test(t => {
|
test(t => {
|
||||||
const div = createDiv(t);
|
const animation = createDiv(t).animate({}, 0);
|
||||||
const animation = div.animate({}, 0);
|
|
||||||
assert_equals(animation.startTime, null,
|
assert_equals(animation.startTime, null,
|
||||||
'Sanity check: start time should be unresolved');
|
'Sanity check: start time should be unresolved');
|
||||||
|
|
||||||
@ -144,8 +142,7 @@ test(t => {
|
|||||||
+ ' current time = target effect end and there is a pending play task');
|
+ ' current time = target effect end and there is a pending play task');
|
||||||
|
|
||||||
test(t => {
|
test(t => {
|
||||||
const div = createDiv(t);
|
const animation = createDiv(t).animate({}, 100 * MS_PER_SEC);
|
||||||
const animation = div.animate({}, 100 * MS_PER_SEC);
|
|
||||||
assert_equals(animation.startTime, null,
|
assert_equals(animation.startTime, null,
|
||||||
'Sanity check: start time should be unresolved');
|
'Sanity check: start time should be unresolved');
|
||||||
|
|
||||||
@ -153,5 +150,36 @@ test(t => {
|
|||||||
}, 'reports \'running\' when playback rate > 0 and'
|
}, 'reports \'running\' when playback rate > 0 and'
|
||||||
+ ' current time < target effect end and there is a pending play task');
|
+ ' current time < target effect end and there is a pending play task');
|
||||||
|
|
||||||
|
test(t => {
|
||||||
|
const animation = createDiv(t).animate({}, 100 * MS_PER_SEC);
|
||||||
|
assert_equals(animation.playState, 'running');
|
||||||
|
assert_true(animation.pending);
|
||||||
|
}, 'reports \'running\' for a play-pending animation');
|
||||||
|
|
||||||
|
test(t => {
|
||||||
|
const animation = createDiv(t).animate({}, 100 * MS_PER_SEC);
|
||||||
|
animation.pause();
|
||||||
|
assert_equals(animation.playState, 'paused');
|
||||||
|
assert_true(animation.pending);
|
||||||
|
}, 'reports \'paused\' for a pause-pending animation');
|
||||||
|
|
||||||
|
test(t => {
|
||||||
|
const animation = createDiv(t).animate({}, 0);
|
||||||
|
assert_equals(animation.playState, 'finished');
|
||||||
|
assert_true(animation.pending);
|
||||||
|
}, 'reports \'finished\' for a finished-pending animation');
|
||||||
|
|
||||||
|
test(t => {
|
||||||
|
const animation = createDiv(t).animate({}, 100 * MS_PER_SEC);
|
||||||
|
// Set up the pending playback rate
|
||||||
|
animation.updatePlaybackRate(-1);
|
||||||
|
// Call play again so that we seek to the end while remaining play-pending
|
||||||
|
animation.play();
|
||||||
|
// For a pending animation, the play state should always report what the
|
||||||
|
// play state _will_ be once we finish pending.
|
||||||
|
assert_equals(animation.playState, 'running');
|
||||||
|
assert_true(animation.pending);
|
||||||
|
}, 'reports the play state based on the pending playback rate');
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
@ -1243,6 +1243,10 @@ function expectedOriginFrecency(urls) {
|
|||||||
* this element can be `undefined`.
|
* this element can be `undefined`.
|
||||||
*/
|
*/
|
||||||
async function checkDB(expectedOrigins) {
|
async function checkDB(expectedOrigins) {
|
||||||
|
// Frencencies for bookmarks are generated asynchronously but not within the
|
||||||
|
// await cycle for bookmarks.insert() etc, so wait for them to happen.
|
||||||
|
await PlacesTestUtils.promiseAsyncUpdates();
|
||||||
|
|
||||||
let db = await PlacesUtils.promiseDBConnection();
|
let db = await PlacesUtils.promiseDBConnection();
|
||||||
let rows = await db.execute(`
|
let rows = await db.execute(`
|
||||||
SELECT prefix, host, frecency
|
SELECT prefix, host, frecency
|
||||||
|
@ -1773,11 +1773,20 @@ this.VideoControlsImplPageWidget = class {
|
|||||||
return new Proxy(element, this.reflowTriggeringCallValidator);
|
return new Proxy(element, this.reflowTriggeringCallValidator);
|
||||||
},
|
},
|
||||||
|
|
||||||
// Set the values to intrinsic dimensions before the first update.
|
|
||||||
reflowedDimensions: {
|
reflowedDimensions: {
|
||||||
|
// Set the dimensions to intrinsic <video> dimensions before the first
|
||||||
|
// update.
|
||||||
|
// These values are not picked up by <audio> in adjustControlSize()
|
||||||
|
// (except for the fact that they are non-zero),
|
||||||
|
// it takes controlBarMinHeight and the value below instead.
|
||||||
videoHeight: 150,
|
videoHeight: 150,
|
||||||
videoWidth: 300,
|
videoWidth: 300,
|
||||||
videocontrolsWidth: 300,
|
|
||||||
|
// <audio> takes this width to grow/shrink controls.
|
||||||
|
// The initial value has to be smaller than the calculated minRequiredWidth
|
||||||
|
// so that we don't run into bug 1495821 (see comment on adjustControlSize()
|
||||||
|
// below)
|
||||||
|
videocontrolsWidth: 0,
|
||||||
},
|
},
|
||||||
|
|
||||||
updateReflowedDimensions() {
|
updateReflowedDimensions() {
|
||||||
@ -1786,6 +1795,29 @@ this.VideoControlsImplPageWidget = class {
|
|||||||
this.reflowedDimensions.videocontrolsWidth = this.videocontrols.clientWidth;
|
this.reflowedDimensions.videocontrolsWidth = this.videocontrols.clientWidth;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* adjustControlSize() considers outer dimensions of the <video>/<audio> element
|
||||||
|
* from layout, and accordingly, sets/hides the controls, and adjusts
|
||||||
|
* the width/height of the control bar.
|
||||||
|
*
|
||||||
|
* It's important to remember that for <audio>, layout (specifically,
|
||||||
|
* nsVideoFrame) rely on us to expose the intrinsic dimensions of the
|
||||||
|
* control bar to properly size the <audio> element. We interact with layout
|
||||||
|
* by:
|
||||||
|
*
|
||||||
|
* 1) When the element has a non-zero height, explicitly set the height
|
||||||
|
* of the control bar to a size between controlBarMinHeight and
|
||||||
|
* controlBarMinVisibleHeight in response.
|
||||||
|
* Note: the logic here is flawed and had caused the end height to be
|
||||||
|
* depend on its previous state, see bug 1495817.
|
||||||
|
* 2) When the element has a outer width smaller or equal to minControlBarPaddingWidth,
|
||||||
|
* explicitly set the control bar to minRequiredWidth, so that when the
|
||||||
|
* outer width is unset, the audio element could go back to minRequiredWidth.
|
||||||
|
* Otherwise, set the width of the control bar to be the current outer width.
|
||||||
|
* Note: the logic here is also flawed; when the control bar is set to
|
||||||
|
* the current outer width, it never go back when the width is unset,
|
||||||
|
* see bug 1495821.
|
||||||
|
*/
|
||||||
adjustControlSize() {
|
adjustControlSize() {
|
||||||
const minControlBarPaddingWidth = 18;
|
const minControlBarPaddingWidth = 18;
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ bool operator<(const EHEntryHandle &lhs, const EHEntryHandle &rhs) {
|
|||||||
class EHTable {
|
class EHTable {
|
||||||
uint32_t mStartPC;
|
uint32_t mStartPC;
|
||||||
uint32_t mEndPC;
|
uint32_t mEndPC;
|
||||||
uint32_t mLoadOffset;
|
uint32_t mBaseAddress;
|
||||||
#ifdef HAVE_UNSORTED_EXIDX
|
#ifdef HAVE_UNSORTED_EXIDX
|
||||||
// In principle we should be able to binary-search the index section in
|
// In principle we should be able to binary-search the index section in
|
||||||
// place, but the ICS toolchain's linker is noncompliant and produces
|
// place, but the ICS toolchain's linker is noncompliant and produces
|
||||||
@ -134,7 +134,7 @@ public:
|
|||||||
const std::string &name() const { return mName; }
|
const std::string &name() const { return mName; }
|
||||||
uint32_t startPC() const { return mStartPC; }
|
uint32_t startPC() const { return mStartPC; }
|
||||||
uint32_t endPC() const { return mEndPC; }
|
uint32_t endPC() const { return mEndPC; }
|
||||||
uint32_t loadOffset() const { return mLoadOffset; }
|
uint32_t baseAddress() const { return mBaseAddress; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class EHAddrSpace {
|
class EHAddrSpace {
|
||||||
@ -548,12 +548,12 @@ EHTable::EHTable(const void *aELF, size_t aSize, const std::string &aName)
|
|||||||
#endif
|
#endif
|
||||||
mName(aName)
|
mName(aName)
|
||||||
{
|
{
|
||||||
const uint32_t base = reinterpret_cast<uint32_t>(aELF);
|
const uint32_t fileHeaderAddr = reinterpret_cast<uint32_t>(aELF);
|
||||||
|
|
||||||
if (aSize < sizeof(Elf32_Ehdr))
|
if (aSize < sizeof(Elf32_Ehdr))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const Elf32_Ehdr &file = *(reinterpret_cast<Elf32_Ehdr *>(base));
|
const Elf32_Ehdr &file = *(reinterpret_cast<Elf32_Ehdr *>(fileHeaderAddr));
|
||||||
if (memcmp(&file.e_ident[EI_MAG0], ELFMAG, SELFMAG) != 0 ||
|
if (memcmp(&file.e_ident[EI_MAG0], ELFMAG, SELFMAG) != 0 ||
|
||||||
file.e_ident[EI_CLASS] != ELFCLASS32 ||
|
file.e_ident[EI_CLASS] != ELFCLASS32 ||
|
||||||
file.e_ident[EI_DATA] != hostEndian ||
|
file.e_ident[EI_DATA] != hostEndian ||
|
||||||
@ -571,7 +571,7 @@ EHTable::EHTable(const void *aELF, size_t aSize, const std::string &aName)
|
|||||||
const Elf32_Phdr *exidxHdr = 0, *zeroHdr = 0;
|
const Elf32_Phdr *exidxHdr = 0, *zeroHdr = 0;
|
||||||
for (unsigned i = 0; i < file.e_phnum; ++i) {
|
for (unsigned i = 0; i < file.e_phnum; ++i) {
|
||||||
const Elf32_Phdr &phdr =
|
const Elf32_Phdr &phdr =
|
||||||
*(reinterpret_cast<Elf32_Phdr *>(base + file.e_phoff
|
*(reinterpret_cast<Elf32_Phdr *>(fileHeaderAddr + file.e_phoff
|
||||||
+ i * file.e_phentsize));
|
+ i * file.e_phentsize));
|
||||||
if (phdr.p_type == PT_ARM_EXIDX) {
|
if (phdr.p_type == PT_ARM_EXIDX) {
|
||||||
exidxHdr = &phdr;
|
exidxHdr = &phdr;
|
||||||
@ -589,15 +589,15 @@ EHTable::EHTable(const void *aELF, size_t aSize, const std::string &aName)
|
|||||||
return;
|
return;
|
||||||
if (!zeroHdr)
|
if (!zeroHdr)
|
||||||
return;
|
return;
|
||||||
mLoadOffset = base - zeroHdr->p_vaddr;
|
mBaseAddress = fileHeaderAddr - zeroHdr->p_vaddr;
|
||||||
mStartPC += mLoadOffset;
|
mStartPC += mBaseAddress;
|
||||||
mEndPC += mLoadOffset;
|
mEndPC += mBaseAddress;
|
||||||
|
|
||||||
// Create a sorted index of the index to work around linker bugs.
|
// Create a sorted index of the index to work around linker bugs.
|
||||||
const EHEntry *startTable =
|
const EHEntry *startTable =
|
||||||
reinterpret_cast<const EHEntry *>(mLoadOffset + exidxHdr->p_vaddr);
|
reinterpret_cast<const EHEntry *>(mBaseAddress + exidxHdr->p_vaddr);
|
||||||
const EHEntry *endTable =
|
const EHEntry *endTable =
|
||||||
reinterpret_cast<const EHEntry *>(mLoadOffset + exidxHdr->p_vaddr
|
reinterpret_cast<const EHEntry *>(mBaseAddress + exidxHdr->p_vaddr
|
||||||
+ exidxHdr->p_memsz);
|
+ exidxHdr->p_memsz);
|
||||||
#ifdef HAVE_UNSORTED_EXIDX
|
#ifdef HAVE_UNSORTED_EXIDX
|
||||||
mEntries.reserve(endTable - startTable);
|
mEntries.reserve(endTable - startTable);
|
||||||
@ -630,13 +630,9 @@ void EHAddrSpace::Update() {
|
|||||||
|
|
||||||
for (size_t i = 0; i < info.GetSize(); ++i) {
|
for (size_t i = 0; i < info.GetSize(); ++i) {
|
||||||
const SharedLibrary &lib = info.GetEntry(i);
|
const SharedLibrary &lib = info.GetEntry(i);
|
||||||
if (lib.GetOffset() != 0)
|
// FIXME: This isn't correct if the start address isn't p_offset 0, because
|
||||||
// TODO: if it has a name, and we haven't seen a mapping of
|
// the start address will not point at the file header. But this is worked
|
||||||
// offset 0 for that file, try opening it and reading the
|
// around by magic number checks in the EHTable constructor.
|
||||||
// headers instead. The only thing I've seen so far that's
|
|
||||||
// linked so as to need that treatment is the dynamic linker
|
|
||||||
// itself.
|
|
||||||
continue;
|
|
||||||
EHTable tab(reinterpret_cast<const void *>(lib.GetStart()),
|
EHTable tab(reinterpret_cast<const void *>(lib.GetStart()),
|
||||||
lib.GetEnd() - lib.GetStart(), lib.GetNativeDebugPath());
|
lib.GetEnd() - lib.GetStart(), lib.GetNativeDebugPath());
|
||||||
if (tab.isValid())
|
if (tab.isValid())
|
||||||
|
@ -43,16 +43,19 @@ int dl_iterate_phdr(
|
|||||||
|
|
||||||
struct LoadedLibraryInfo
|
struct LoadedLibraryInfo
|
||||||
{
|
{
|
||||||
LoadedLibraryInfo(const char* aName, unsigned long aStart, unsigned long aEnd)
|
LoadedLibraryInfo(const char* aName, unsigned long aBaseAddress,
|
||||||
|
unsigned long aFirstMappingStart, unsigned long aLastMappingEnd)
|
||||||
: mName(aName)
|
: mName(aName)
|
||||||
, mStart(aStart)
|
, mBaseAddress(aBaseAddress)
|
||||||
, mEnd(aEnd)
|
, mFirstMappingStart(aFirstMappingStart)
|
||||||
|
, mLastMappingEnd(aLastMappingEnd)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCString mName;
|
nsCString mName;
|
||||||
unsigned long mStart;
|
unsigned long mBaseAddress;
|
||||||
unsigned long mEnd;
|
unsigned long mFirstMappingStart;
|
||||||
|
unsigned long mLastMappingEnd;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(GP_OS_android)
|
#if defined(GP_OS_android)
|
||||||
@ -134,8 +137,9 @@ dl_iterate_callback(struct dl_phdr_info *dl_info, size_t size, void *data)
|
|||||||
if (dl_info->dlpi_phnum <= 0)
|
if (dl_info->dlpi_phnum <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
unsigned long libStart = -1;
|
unsigned long baseAddress = dl_info->dlpi_addr;
|
||||||
unsigned long libEnd = 0;
|
unsigned long firstMappingStart = -1;
|
||||||
|
unsigned long lastMappingEnd = 0;
|
||||||
|
|
||||||
for (size_t i = 0; i < dl_info->dlpi_phnum; i++) {
|
for (size_t i = 0; i < dl_info->dlpi_phnum; i++) {
|
||||||
if (dl_info->dlpi_phdr[i].p_type != PT_LOAD) {
|
if (dl_info->dlpi_phdr[i].p_type != PT_LOAD) {
|
||||||
@ -143,14 +147,16 @@ dl_iterate_callback(struct dl_phdr_info *dl_info, size_t size, void *data)
|
|||||||
}
|
}
|
||||||
unsigned long start = dl_info->dlpi_addr + dl_info->dlpi_phdr[i].p_vaddr;
|
unsigned long start = dl_info->dlpi_addr + dl_info->dlpi_phdr[i].p_vaddr;
|
||||||
unsigned long end = start + dl_info->dlpi_phdr[i].p_memsz;
|
unsigned long end = start + dl_info->dlpi_phdr[i].p_memsz;
|
||||||
if (start < libStart)
|
if (start < firstMappingStart) {
|
||||||
libStart = start;
|
firstMappingStart = start;
|
||||||
if (end > libEnd)
|
}
|
||||||
libEnd = end;
|
if (end > lastMappingEnd) {
|
||||||
|
lastMappingEnd = end;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
libInfoList->AppendElement(LoadedLibraryInfo(dl_info->dlpi_name,
|
libInfoList->AppendElement(LoadedLibraryInfo(dl_info->dlpi_name, baseAddress,
|
||||||
libStart, libEnd));
|
firstMappingStart, lastMappingEnd));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -244,7 +250,10 @@ SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf()
|
|||||||
|
|
||||||
for (const auto& libInfo : libInfoList) {
|
for (const auto& libInfo : libInfoList) {
|
||||||
info.AddSharedLibrary(
|
info.AddSharedLibrary(
|
||||||
SharedLibraryAtPath(libInfo.mName.get(), libInfo.mStart, libInfo.mEnd));
|
SharedLibraryAtPath(libInfo.mName.get(),
|
||||||
|
libInfo.mFirstMappingStart,
|
||||||
|
libInfo.mLastMappingEnd,
|
||||||
|
libInfo.mFirstMappingStart - libInfo.mBaseAddress));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(GP_OS_linux)
|
#if defined(GP_OS_linux)
|
||||||
|
@ -103,9 +103,10 @@ interface nsIProfiler : nsISupports
|
|||||||
* Every object has the properties:
|
* Every object has the properties:
|
||||||
* - start: The start address of the memory region occupied by this library.
|
* - start: The start address of the memory region occupied by this library.
|
||||||
* - end: The end address of the memory region occupied by this library.
|
* - end: The end address of the memory region occupied by this library.
|
||||||
* - offset: Usually zero, except on Android if the region was mapped from
|
* - offset: Usually zero, except on Linux / Android if the first mapped
|
||||||
* a file (using mmap), then this is the offset in the file where
|
* section of the library has been mapped to an address that's
|
||||||
* the mapping begins.
|
* different from the library's base address.
|
||||||
|
* Then offset = start - baseAddress.
|
||||||
* - name: The name (file basename) of the binary.
|
* - name: The name (file basename) of the binary.
|
||||||
* - path: The full absolute path to the binary.
|
* - path: The full absolute path to the binary.
|
||||||
* - debugName: On Windows, the name of the pdb file for the binary. On other
|
* - debugName: On Windows, the name of the pdb file for the binary. On other
|
||||||
|
Loading…
Reference in New Issue
Block a user